package com.jumi.microservice.mq;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.openservices.ons.api.Action;
import com.aliyun.openservices.ons.api.ConsumeContext;
import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.MessageListener;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.jumi.microservice.dto.wallet.api.WalletInOrOutRequest;
import com.jumi.microservice.entity.JmExtraDiscount;
import com.jumi.microservice.entity.JmExtraDiscountLog;
import com.jumi.microservice.entity.JmUser;
import com.jumi.microservice.entity.JmUserFenxiao;
import com.jumi.microservice.enums.CommonEnum;
import com.jumi.microservice.enums.FenXiaoStatus;
import com.jumi.microservice.service.*;
import com.jumi.microservice.util.WrapperUtil;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 订单完成,确认收货接收mq 将受益转为可到账
 *
 * @author 123
 */
@Component
public class OrderAccomplishListener implements MessageListener {
    @Resource
    IErrOrderAfterMsgService errOrderAfterMsgService;

    @Resource
    IJmUserFenxiaoService fenxiaoService;

    @DubboReference(check = false)
    IWalletInOrOutService walletInOrOutService;

    @Resource
    IJmUserService userService;

    @Resource
    IJmExtraDiscountLogService discountLogService;

    @Resource
    IJmExtraDiscountService discountService;

    Logger logger = LoggerFactory.getLogger(OrderAccomplishListener.class);



    /**
     * 处理额外折扣
     * @param logId
     * @param uid
     * @param yongjin
     */
    private void dealExtraDiscount(Integer logId, Integer uid, BigDecimal yongjin) {
        // 更新额外折扣日志状态
        UpdateWrapper updateWrapper=new UpdateWrapper();
        updateWrapper.set("status",FenXiaoStatus.已结算.getValue());
        updateWrapper.eq("id",logId);
        boolean res = discountLogService.update(updateWrapper);
        logger.info("更新额外折扣日志状态 [{}]",res);
        // 新增或更新额外折扣当前金额
        QueryWrapper queryWrapper=new QueryWrapper();
        queryWrapper.eq("uid",uid);
        JmExtraDiscount discount= discountService.getOne(queryWrapper);
        if(ObjectUtil.isEmpty(discount)){
            discount = new JmExtraDiscount();
            discount.setUid(uid);
            discount.setDiscount(yongjin);
            Long currentSeconds=DateUtil.currentSeconds();
            discount.setAddTime(currentSeconds.intValue());
            res = discountService.save(discount);
            logger.info("新增额外折扣当前金额 [{}]",res);
        }else{
            BigDecimal disc=discount.getDiscount().add(yongjin);
            discount.setDiscount(disc);
            res = discountService.updateById(discount);
            logger.info("更新额外折扣当前金额 [{}]",res);
        }
    }


    @Override
    @Transactional
    public Action consume(Message message, ConsumeContext context) {
        logger.info("从orderAccomplish队列收到消息[{}]", new String(message.getBody()));
        String m = new String(message.getBody());
        JSONObject jsonObject = JSON.parseObject(m);
        Integer buyerId = jsonObject.getInteger("buyerId");
        String orderNo = jsonObject.getString("orderNo");
        JmUserFenxiao fenxiao = new JmUserFenxiao();
        fenxiao.setStatus(FenXiaoStatus.未结算);
        fenxiao.setIsDel(CommonEnum.否);
        fenxiao.setBuyerId(buyerId);
        fenxiao.setOrderSn(orderNo);
        QueryWrapper wrapper = WrapperUtil.getWrapper(null, fenxiao);
        //更新extra_discount记录
        List<JmExtraDiscountLog> logs = discountLogService.list(wrapper);
        logger.info("extra_discount_log记录 数据[{}]",JSON.toJSONString(logs));
        for (JmExtraDiscountLog log : logs) {
            Integer logId = log.getId();
            Integer uid = log.getUid();
            BigDecimal yongjin = log.getYongjin();
            this.dealExtraDiscount(logId,uid,yongjin);
        }

        List<JmUserFenxiao> list = fenxiaoService.list(wrapper);
        //批量入账
        List<WalletInOrOutRequest> walletInList = new ArrayList<>();
        //用户的收益
        BigDecimal bd = BigDecimal.ZERO;
        logger.info("买家ID[{}]订单编号[{}]查询到的符合条件数据量[{}]", buyerId, orderNo, list.size());
        if (ObjectUtil.isNotEmpty(list)) {
            for (JmUserFenxiao jmUserFenxiao : list) {
                WalletInOrOutRequest request = new WalletInOrOutRequest();
                BigDecimal yongjin = jmUserFenxiao.getYongjin();
                request.setAmount(yongjin);
                request.setOrderNo(jmUserFenxiao.getOrderSn());
                request.setType(jmUserFenxiao.getType().getValue());
                request.setUserId(jmUserFenxiao.getUid().longValue());
                jmUserFenxiao.setStatus(FenXiaoStatus.已结算);
                jmUserFenxiao.setUpdateTime(LocalDateTime.now());
                walletInList.add(request);
                bd.add(yongjin);
            }
            JmUser jmUser = userService.getById(Convert.toInt(buyerId));
            if (ObjectUtil.isNotEmpty(jmUser)) {
                //更新用户的可提现金额;
                //用户可提现余额
                BigDecimal availablePredeposit = jmUser.getAvailablePredeposit();
                availablePredeposit = availablePredeposit.add(bd);
                jmUser.setAvailablePredeposit(availablePredeposit);
                userService.updateById(jmUser);
            }
            //更新用户收益记录为已结算
            fenxiaoService.updateBatchById(list);
            try {
                //调用钱包服务
                walletInOrOutService.batchWalletIn(walletInList);
            } catch (Exception e) {
                logger.error(StrUtil.format("wallet 服务调用错误{}", e.getMessage()));
            }
        }
        logger.info("订单完成消息消费结束---->");
        return Action.CommitMessage;
    }
}
